/**
 * 
 */
package org.tigris.apexam.implementation;

import java.util.*;

import org.tigris.apexam.AbstractSection;
import org.tigris.apexam.ExpressionSection;
import org.tigris.apexam.IdentifierSection;
import org.tigris.apexam.Message;
import org.tigris.apexam.TextSection;
import org.tigris.elfin.*;

/**
 * @author zhisen.huang
 * 
 */
public class SimpleMessage implements Message {

	protected AbstractSection[] sections;

	protected String messageName;

	protected String messageBody;
	
	protected static char leftChar, rightChar;

	protected ExpressionProcessor expressionProcessor = null;

	public SimpleMessage(String messageName, String messageBody) {
		this(messageName, messageBody, '<', '>');
	}
	
	public SimpleMessage(String messageName, String messageBody, char leftChar, char rightChar) {
		this.messageName = messageName;
		this.messageBody = messageBody;
		sections = initialize(messageBody);
		this.leftChar = leftChar;
		this.rightChar = rightChar;
	}

	public static AbstractSection[] initialize(String messageBody) {
		int leftBrace = messageBody.indexOf(leftChar);
		int rightBrace = 0;

		List<AbstractSection> sections = new ArrayList<AbstractSection>();

		while (leftBrace >= 0) {

			if (leftBrace > 0) {
				String text = messageBody.substring(rightBrace + 1, leftBrace);
				AbstractSection textSection = new TextSection();
				textSection.setSectionBody(text);
				//System.out.println(text);
				sections.add(textSection);
			}
			rightBrace = messageBody.indexOf(rightChar, leftBrace + 1);
			String expression = messageBody
					.substring(leftBrace + 1, rightBrace);

			AbstractSection expressionSection = new ExpressionSection();
			expressionSection.setSectionBody(expression);
			sections.add(expressionSection);
			//System.out.println("ex: " + expression);
			leftBrace = messageBody.indexOf(leftChar, rightBrace + 1);
			//System.out.println("messageBody: " + messageBody.length());
			//System.out.println("leftBrace: " + leftBrace);
		}
		if (rightBrace < messageBody.length()) {
			String text = messageBody.substring(rightBrace + 1);
			AbstractSection textSection = new TextSection();
			textSection.setSectionBody(text);
			sections.add(textSection);
		}
		return sections.toArray(new AbstractSection[] {});
	}

	public String getMessage(Map<String, Object> params) throws Exception {
		StringBuffer buffer = new StringBuffer();

		for (AbstractSection section : sections) {
			if (section instanceof TextSection) {
				buffer.append(processSection((TextSection) section));
			} else if (section instanceof IdentifierSection) {
				buffer.append(processSection((IdentifierSection) section,
						params));
			} else {
				buffer.append(processSection((ExpressionSection) section,
						params));
			}
		}
		return buffer.toString();
	}

	public String processSection(TextSection section) {
		return section.getSectionBody();
	}

	public String processSection(IdentifierSection section,
			Map<String, Object> variables) throws Exception {
		String name = section.getSectionBody();
		int dot = name.lastIndexOf('.');
		if (dot < 0) {
			return (String) variables.get(name);
		}
		String propertyName = name.substring(dot + 1, name.length());
		String objectName = name.substring(0, dot);
		Object object = variables.get(objectName);
		return BeanCapturer.getValue(propertyName, object);
	}

	public String processSection(ExpressionSection section,
			Map<String, Object> params) throws Exception {
		return expressionProcessor.evaluate(section.getSectionBody(), params);
	}

	/**
	 * @param expressionProcessor
	 *            the expressionProcessor to set
	 */
	public void setExpressionProcessor(ExpressionProcessor expressionProcessor) {
		this.expressionProcessor = expressionProcessor;
	}
}
